package com.ccrfid.rmc6.lbservice3.mq;

import com.ccrfid.rmc6.lbservice3.pojo.msg.MsgType;
import com.ccrfid.rmc6.util.JsonUtil;
import com.google.common.eventbus.EventBus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.jms.annotation.JmsListener;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

//MP: MessageProcessor

@Component
public class MPMsgReceiver {
    private static final Logger logger = LoggerFactory.getLogger(MPMsgReceiver.class);

    @Value("${topic.mp_personnel_alarm.enabled}")
    private boolean enableTopicMpPersonnelAlarm;
    @Value("${topic.mp_location_alarm.enabled}")
    private boolean enableTopicMpLocationAlarm;
    @Value("${topic.aoa_tags_position.enabled}")
    private boolean enableTopicAoaTagsPosition;
    @Value("${topic.aoa_tags_status.enabled}")
    private boolean enableTopicAoaTagsStatus;
    @Value("${topic.mp_devices_move.enabled}")
    private boolean enableTopicMpDevicesMove;
    @Value("${topic.mp_devices_real.enabled}")
    private boolean enableTopicMpDevicesReal;

    @Autowired
    private MsgDispatcher msgDispatcher;
    @Autowired
    private EventBus eventBus;

    //人员告警消息
    @JmsListener(destination = "mp_personnel_alarm", containerFactory = "topicListenerCF")
    public void onMpPersonnelAlarm(String content) {
        if (enableTopicMpPersonnelAlarm) {
            logger.info("recv from topic[mp_personnel_alarm]: {}", content);
            MqPersonnelAlarm personnelAlarm = JsonUtil.INSTANCE.readValue(content, MqPersonnelAlarm.class);
            //推送人员告警
            if (!msgDispatcher.inputData(personnelAlarm)) {
                logger.error("MsgDispatcher inputData return: false, so ignore personnelAlarm: {}", personnelAlarm);
            }
        }
    }

    //区域告警消息
    @JmsListener(destination = "mp_location_alarm", containerFactory = "topicListenerCF")
    public void onMpLocationAlarm(String content) {
        if (enableTopicMpLocationAlarm) {
            logger.info("recv from topic[mp_location_alarm]: {}", content);
            MqLocationAlarm locationAlarm = JsonUtil.INSTANCE.readValue(content, MqLocationAlarm.class);
            if (locationAlarm.getPersonnels() != null && locationAlarm.getPersonnels().size() > 0) {
                locationAlarm.getPersonnels().removeIf(value -> value == 0);
            }
            //推送区域告警
            if (!msgDispatcher.inputData(locationAlarm)) {
                logger.error("MsgDispatcher inputData return: false, so ignore locationAlarm: {}", locationAlarm);
            }
        }
    }

    //互监告警、非法同行告警消息
    @JmsListener(destination = "mp_personnel_group", containerFactory = "topicListenerCF")
    public void onMpPersonnelGroupAlarm(String content) {
        logger.debug("recv from topic[mp_personnel_group]: {}", content);
        MqPersonnelGroupAlarm groupAlarm = JsonUtil.INSTANCE.readValue(content, MqPersonnelGroupAlarm.class);
        //推送区域告警
        if (!msgDispatcher.inputData(groupAlarm)) {
            logger.error("MsgDispatcher inputData return: false, so ignore personnelGroupAlarm: {}", groupAlarm);
        }
    }

    //精确定位标签坐标
    @JmsListener(destination = "aoa_tags_position", containerFactory = "topicListenerCF")
    public void onMqTagsPosition(String content) {
        if (enableTopicAoaTagsPosition) {
            logger.trace("recv from topic[aoa_tags_position]: {}", content);
            MqTagPosition[] list = JsonUtil.INSTANCE.readValue(content, MqTagPosition[].class);
            for (MqTagPosition mqTagPosition : list) {
                if (mqTagPosition != null) {
                    boolean success = msgDispatcher.inputData(mqTagPosition);
                    if (!success) {
                        logger.error("MsgDispatcher inputData return: false, so ignore mqTagPosition: {}", mqTagPosition);
                        try {
                            TimeUnit.MILLISECONDS.sleep(40);
                        } catch (InterruptedException ex) {
                            ex.printStackTrace();
                        }
                    }
                }
            }
        }
    }

    //精确定位标签状态
    @JmsListener(destination = "aoa_tags_status", containerFactory = "topicListenerCF")
    public void onMqTagStatus(String content) {
        if (enableTopicAoaTagsStatus) {
            logger.trace("recv from topic[aoa_tags_status]: {}", content);
            MqTagStatus[] list = JsonUtil.INSTANCE.readValue(content, MqTagStatus[].class);
            for (MqTagStatus mqTagStatus : list) {
                if (mqTagStatus != null) {
                    boolean success = msgDispatcher.inputData(mqTagStatus);
                    if (!success) {
                        logger.error("MsgDispatcher inputData return: false, so ignore mqTagStatus: {}", mqTagStatus);
                        try {
                            TimeUnit.MILLISECONDS.sleep(40);
                        } catch (InterruptedException ex) {
                            ex.printStackTrace();
                        }
                    }
                }
            }
        }
    }

    //标签移动消息
    @JmsListener(destination = "mp_devices_move", containerFactory = "topicListenerCF")
    public void onMpDevicesMove(String content) {
        if (enableTopicMpDevicesMove) {
            recvMqMsg("mp_devices_move", content);
        }
    }

    //标签实时消息
    @JmsListener(destination = "mp_devices_real", containerFactory = "topicListenerCF")
    public void onMpDevicesReal(String content) {
        if (enableTopicMpDevicesReal) {
            recvMqMsg("mp_devices_real", content);
        }
    }

    private void recvMqMsg(String topic, String content) {
        logger.trace("recv from topic[{}]: {}", topic, content);
        MqMsgDev[] list = JsonUtil.INSTANCE.readValue(content, MqMsgDev[].class);
        for (MqMsgDev msgDev : list) {
            if (msgDev != null) {
                switch (msgDev.getMsgType()) {
                    case MsgType.DEVICE_MESSAGE_TYPE_BEATHEART:
                        inputData(msgDev);
                        break;
                    case MsgType.DEVICE_MESSAGE_TYPE_CUT:
                        inputData(msgDev);
                        break;
                    case MsgType.DEVICE_MESSAGE_TYPE_OFFLINE:
                        break;
                    case MsgType.DEVICE_MESSAGE_TYPE_ENTERLOCATOR:
                        inputLocateData(msgDev);
                        break;
                    case MsgType.DEVICE_MESSAGE_TYPE_LEAVELOCATOR:
                        inputLocateData(msgDev);
                        break;
                    case MsgType.DEVICE_MESSAGE_TYPE_CALL:
                        inputData(msgDev);
                        break;
                    case MsgType.DEVICE_MESSAGE_TYPE_OFFALARM:
                        break;
                    case MsgType.DEVICE_MESSAGE_TYPE_LOWPWR:
                        inputData(msgDev);
                        break;
                    case MsgType.DEVICE_MESSAGE_TYPE_NORMALPWR:
                        inputData(msgDev);
                        break;
                    case MsgType.DEVICE_MESSAGE_TYPE_ONLINE:
                        break;
                    case MsgType.DEVICE_MESSAGE_TYPE_HEARTRATE:
                        inputLocateData(msgDev);
                        break;
                    case MsgType.DEVICE_MESSAGE_TYPE_POWER:
                        inputLocateData(msgDev);
                        break;
                    case MsgType.DEVICE_MESSAGE_TYPE_LOCATE:
                        inputLocateData(msgDev);
                        break;
                    case MsgType.DEVICE_MESSAGE_TYPE_STEP:
                        inputLocateData(msgDev);
                        break;
                    case MsgType.DEVICE_MESSAGE_TYPE_TEMPERATURE:
                        inputLocateData(msgDev);
                        break;
                    case MsgType.DEVICE_MESSAGE_TYPE_BLOOD_PRESSURE:
                        inputLocateData(msgDev);
                        break;
                }
            }
        }
    }

    private void inputData(MqMsgDev msgDev) {
        boolean success = msgDispatcher.inputData(msgDev);
        if (!success) {
            logger.error("MsgDispatcher inputData return: {}, so ignore mqMsg: {}", success, msgDev);
            try {
                TimeUnit.MILLISECONDS.sleep(40);
            } catch (InterruptedException ex) {
                ex.printStackTrace();
            }
        }
    }

    private void inputLocateData(MqMsgDev msgDev) {
        boolean success = msgDispatcher.inputLocateData(msgDev);
        if (!success) {
            logger.error("MsgDispatcher inputLocateData return: {}, so ignore mqMsg: {}", success, msgDev);
            try {
                TimeUnit.MILLISECONDS.sleep(40);
            } catch (InterruptedException ex) {
                ex.printStackTrace();
            }
        }
    }

    //定位器/阅读器在线状态消息
    @JmsListener(destination = "mp_devices_status", containerFactory = "topicListenerCF")
    public void onMpDevicesStatus(String content) {
        logger.trace("recv from topic[mp_devices_status]: {}", content);
        MqDevStatus[] list = JsonUtil.INSTANCE.readValue(content, MqDevStatus[].class);
        for (MqDevStatus mqDevStatus : list) {
            if (mqDevStatus != null) {
                eventBus.post(mqDevStatus);
            }
        }
    }
}
